import Data from '../components/Data.js'

const CFG_PATH = 'resources/config/artifact_rates.json'
const ART_SETS_PATH = 'resources/data/Artifact/圣遗物.json'

const merge = (a, b) => {
  if (!b || typeof b !== 'object') return a
  const r = Array.isArray(a) ? [...a] : { ...a }
  for (const k of Object.keys(a)) r[k] = merge(a[k], b[k])
  for (const k of Object.keys(b)) if (!(k in a)) r[k] = b[k]
  return r
}

const defaults = {
  main: {
    flower: { min: 0.0004, max: 0.0007 },
    feather: { min: 0.0004, max: 0.0007 },
    sand: {
      weights: {
        '生命加成百分比': 1.0,
        '防御加成百分比': 0.9,
        '攻击加成百分比': 0.8,
        '速度加成百分比': 0.7,
        '首领破防百分比': 0.6
      },
      min: 0.0004, max: 0.0007
    },
    goblet: {
      element_weights: { '金': 1, '木': 1, '水': 1, '火': 1, '土': 1 },
      min: 0.0004, max: 0.0007
    },
    circlet: {
      weights: {
        '生命加成百分比': 1.0,
        '首领破防百分比': 0.6,
        '暴击率': 0.08,
        '暴击伤害': 0.07,
        '幸运加成百分比': 0.05
      },
      min: 0.0003, max: 0.0007,
      lucky_min: 0.0001, lucky_max: 0.0003
    }
  },
  tiers: {
    '1': { init_sub_min: 1, init_sub_max: 2, max_sub: 3, main_scale: 0.55, sub_scale: 0.55 },
    '2': { init_sub_min: 1, init_sub_max: 2, max_sub: 3, main_scale: 0.65, sub_scale: 0.65 },
    '3': { init_sub_min: 1, init_sub_max: 2, max_sub: 3, main_scale: 0.8, sub_scale: 0.8 },
    '4': { init_sub_min: 2, init_sub_max: 3, max_sub: 4, main_scale: 0.95, sub_scale: 0.95 },
    '5': { init_sub_min: 2, init_sub_max: 3, max_sub: 4, main_scale: 1.0, sub_scale: 1.0 }
  },
  sub: {
    count_min: 2,
    count_max: 3,
    base_weights: {
      '生命': 1.0,
      '防御': 0.9,
      '攻击': 0.8,
      '速度': 0.7,
      '破防': 0.6,
      '暴击率': 0.15,
      '暴击伤害': 0.15,
      '幸运': 0.05
    },
    percent_bias: 0.6
  },
  ranges: {
    default_percent_min: 0.0001,
    default_percent_max: 0.0003,
    default_flat_min: 0.0001,
    default_flat_max: 0.0003
  }
}

const safeRead = (path, def) => {
  try { return Data.readJSON(path, def) } catch (_) { return def }
}

const getRates = () => merge(defaults, safeRead(CFG_PATH, {}))

const rnd = (min, max) => Math.round(((min + (max - min) * Math.random())) * 10000) / 10000
const pickWeighted = (weights) => {
  const entries = Object.entries(weights).filter(([, w]) => Number(w) > 0)
  const sum = entries.reduce((a, [, w]) => a + Number(w), 0)
  let r = Math.random() * sum
  for (const [k, w] of entries) { r -= Number(w); if (r <= 0) return k }
  return entries[entries.length - 1]?.[0]
}

const normalizeSubKeys = () => ([
  '生命', '防御', '攻击', '速度', '破防',
  '暴击率', '暴击伤害',
  '生命加成百分比', '防御加成百分比', '攻击加成百分比', '速度加成', '破防加成', '幸运加成百分比'
])

const isPercentKey = (key) => /百分比/.test(key) || key === '幸运加成百分比'

const pickSetPart = (sets, star, part) => {
  const pool = Array.isArray(sets) ? sets.filter(s => s['星级'] === star) : []
  const set = pool[Math.floor(Math.random() * Math.max(pool.length, 1))] || {}
  const parts = Array.isArray(set['部件']) ? set['部件'] : []
  const base = parts.find(p => p['部位'] === part) || {}
  return { set, base }
}

const buildItemBase = (set, base, part) => ({
  类别: '圣遗物', 套装名称: set['套装名称'], 元素: set['元素'], 星级: set['星级'], 稀有度: set['稀有度'], id: base?.id, 名称: base?.['名称'], 部位: part,
  生命: 0,
  防御: 0,
  速度: 0,
  生命加成百分比: 0,
  防御加成百分比: 0,
  攻击: 0,
  攻击加成百分比: 0,
  速度加成百分比: 0,
  暴击率: 0,
  暴击伤害: 0,
  首领破防百分比: 0,
  元素伤害加成百分比: 0,
  幸运加成百分比: 0,
  副词条: []
})

const applyMainStat = (item, part, rates, tier) => {
  if (part === '花') {
    item['生命'] = rnd(rates.main.flower.min, rates.main.flower.max) * (tier?.main_scale ?? 1)
  } else if (part === '羽') {
    item['攻击'] = rnd(rates.main.feather.min, rates.main.feather.max) * (tier?.main_scale ?? 1)
  } else if (part === '沙') {
    const key = pickWeighted(rates.main.sand.weights)
    const v = rnd(rates.main.sand.min, rates.main.sand.max) * (tier?.main_scale ?? 1)
    item[key] = v
  } else if (part === '杯') {
    const elem = pickWeighted(rates.main.goblet.element_weights)
    const v = rnd(rates.main.goblet.min, rates.main.goblet.max) * (tier?.main_scale ?? 1)
    item['元素伤害加成百分比'] = v
    item['元素'] = elem
  } else if (part === '冠') {
    const key = pickWeighted(rates.main.circlet.weights)
    const v = (key === '幸运加成百分比'
      ? rnd(rates.main.circlet.lucky_min, rates.main.circlet.lucky_max)
      : rnd(rates.main.circlet.min, rates.main.circlet.max)) * (tier?.main_scale ?? 1)
    item[key] = v
  }
}

const applySubStats = (item, rates, tier) => {
  const initMin = tier?.init_sub_min ?? rates.sub.count_min
  const initMax = tier?.init_sub_max ?? rates.sub.count_max
  const maxSub = tier?.max_sub ?? rates.sub.count_max
  let subCount = Math.floor(initMin + Math.random() * (initMax - initMin + 1))
  if (subCount > maxSub) subCount = maxSub
  const all = normalizeSubKeys()
  const weights = {}
  for (const k of all) {
    const baseType = k.replace('加成百分比', '').replace('加成', '')
    const wBase = rates.sub.base_weights[baseType] ?? 0.1
    const pct = isPercentKey(k)
    weights[k] = wBase * (pct ? rates.sub.percent_bias : 1)
  }
  const chosen = new Set()
  while (chosen.size < subCount) {
    const key = pickWeighted(weights)
    if (key && !chosen.has(key)) chosen.add(key)
  }
  for (const key of chosen) {
    const pct = isPercentKey(key)
    const min = pct ? rates.ranges.default_percent_min : rates.ranges.default_flat_min
    const max = pct ? rates.ranges.default_percent_max : rates.ranges.default_flat_max
    const v = rnd(min, max) * (tier?.sub_scale ?? 1)
    item[key] = (Number(item[key]) || 0) + v
    item['副词条'].push({ 键: key, 值: v })
  }
}

const generateArtifact = (part, star = 2) => {
  const rates = getRates()
  const sets = safeRead(ART_SETS_PATH, [])
  const tier = rates.tiers?.[String(star)] || rates.tiers?.['2']
  const { set, base } = pickSetPart(sets, star, part)
  const item = buildItemBase(set, base, part)
  applyMainStat(item, part, rates, tier)
  applySubStats(item, rates, tier)
  return item
}

const generateRandomArtifact = (star = 2) => {
  const parts = ['花', '羽', '沙', '杯', '冠']
  const part = parts[Math.floor(Math.random() * parts.length)]
  return generateArtifact(part, star)
}

export default { getRates, generateArtifact, generateRandomArtifact }
export const generateArtifactFromBase = (base) => {
  const rates = getRates()
  const part = base['部位']
  const star = base['星级']
  const tier = rates.tiers?.[String(star)] || rates.tiers?.['2']
  const item = buildItemBase({ '套装名称': base['套装名称'], '元素': base['元素'], '星级': base['星级'], '稀有度': base['稀有度'] }, { id: base.id, 名称: base['名称'] }, part)
  applyMainStat(item, part, rates, tier)
  applySubStats(item, rates, tier)
  item['掉落来源'] = base['掉落来源'] || []
  item['概率'] = base['概率'] || {}
  return item
}
